import { RoundRectPath } from "./interface"

export default class PointIn{
    /**
     * 判断点(x,y)是否在以(cx,cy)为圆心 r 为半径的圆内
     * @param {number} x 点的x坐标
     * @param {number} y 点的y坐标
     * @param {number} cx 圆心x坐标
     * @param {number} cy 圆心y坐标
     * @param {number} r 圆半径
     */
    static circle(x: number, y:number, cx:number, cy: number, r:number): boolean{
        let dx = x - cx
        let dy = y - cy
        let dr = Math.sqrt(dx * dx + dy * dy)
        return dr < r
    }
    /**
     * 判断点(x,y)是否在矩形path以内
     * @param {number} x 
     * @param {number} y 
     * @param {RoundRectPath} path 
     */
    static rect(x:number, y:number, path: RoundRectPath): boolean{
        let px = path.x
        let py = path.y
        let width = path.width
        let height = path.height
        if(x < px || y < py || x > px + width || y > py + height) return false
        return true
    }
    /**
     * 判断点(x,y)是否在圆角矩形path以内
     * @param {number} x 
     * @param {number} y 
     * @param {RoundRectPath} path 
     */
    static roundRect(x:number, y:number, path: RoundRectPath): boolean{
        let px = path.x
        let py = path.y
        let radius = path.radius
        let width = path.width
        let height = path.height

        if(x < px || y < py || x > px + width || y > py + height) return false
        let r = radius[0]
        let cx = px+r
        let cy = py+r
        if(x < cx && y < cy && !this.circle(x, y, cx, cy, r)) return false
        r = radius[1]
        cx = px+width-r
        cy = py+r
        if(x > cx && y < cy && !this.circle(x, y, cx, cy, r)) return false
        r = radius[2]
        cx = px+width-r
        cy = py+height-r
        if(x > cx && y > cy && !this.circle(x, y, cx, cy, r)) return false
        r = radius[3]
        cx = px+r
        cy = py+height-r
        if(x < cx && y > cy && !this.circle(x, y, cx, cy, r)) return false
        return true
    }
    /**
     * 求点(x, y)绕点(cx, cy)旋转d度后的坐标
     * @param {number} x 
     * @param {number} y 
     * @param {number} cx 
     * @param {number} cy 
     * @param {number} d 单位：弧度
     * @returns 
     */
    static rotatePoint(x:number, y:number, cx:number, cy:number, d:number): number[]{
		let cos = Math.cos(d)
		let sin = Math.sin(d)
		let newX = (x - cx) * cos - (y - cy) * sin + cx
		let newY = (x - cx) * sin + (y - cy) * cos + cy
		return [newX, newY]
	}
    /**
	 * 求线段AB上的任意位置的坐标
	 * @param x0 A点的x坐标
	 * @param y0 A点的y坐标
	 * @param x1 B点的x坐标
	 * @param y1 B点的y坐标
	 * @param ratio C点的位置比例值，即s = AC/AB
	 */
    static linePoint(x0:number, y0:number, x1:number, y1:number, ratio:number):number[]{
        let k, b, x, y;
        if(x0 === x1){
            x = x0;
            y = ratio * (y1 - y0) + y0;
        }else{
            k = (y1 - y0) / (x1 - x0); //斜率
            b = y0 - k * x0;
            x = ratio * (x1 - x0) + x0;
            y = k * x + b;
        }
        return [x, y];
    }
    /**
	 * 获取系列控制点的(n阶)bezier曲线上的点
	 * @param points 控制点系列[x0,y0,x1,y1,x2,y2,,,,]，至少两个点，即length >=4
	 * @param ratio 位置比或时间比
	 */
	static bezierPoint(points:number[], ratio: number, fn?:Function):number[]{
		let len:number = points.length, arr:number[], tmp:number[] = points;
		if(len%2) len--;
		while(len >= 4){
			arr = [];
			for(let i=0, point; i+2<len; i+=2){
				point = this.linePoint(tmp[i], tmp[i+1], tmp[i+2], tmp[i+3], ratio);
				arr.push(point[0], point[1]);
			}
			if(fn) fn(arr);
			len = arr.length;
			tmp = arr;
		}
		return arr;
	}
}